package com.itheima.edu.info.manager.controller;

import com.itheima.edu.info.manager.domain.Option;
import com.itheima.edu.info.manager.domain.Student;

import java.io.*;
import java.net.Socket;
import java.util.Scanner;


public abstract class BaseStudentController {


    //该方法是用来获取一个指定的客户端套接字socket("127.0.0.1", 10088)
    public Socket getSocket() {
        Socket socket = null;
        try {
            socket = new Socket("127.0.0.1", 10088);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            return socket;
        }
    }

    //创建一个录入信息的扫描类
    private Scanner sc = new Scanner(System.in);

    // 开启学生管理系统, 并展示学生管理系统菜单
    public final void start() {
        while (true) {
            //开始菜单的提示信息
            System.out.println("--------欢迎来到 <学生> 管理系统--------");
            System.out.println("请输入您的选择: 1.添加学生  2.删除学生  3.修改学生  4.查看学生  5.退出");
            String choice = sc.next();
            switch (choice) {
                case "1":
                    addStudent();
                    break;
                case "2":
                    deleteStudentById();
                    break;
                case "3":
                    updateStudentById();
                    break;
                case "4":
                    findAllStudents();
                    break;
                case "5":
                    System.out.println("感谢您使用学生管理系统, 再见!");
                    return;
                default:
                    System.out.println("您的输入有误, 请重新输入");
                    break;
            }
        }
    }

    //修改指定id的学生对象
    protected void updateStudentById() {
        //1. 键盘录入一个可用的学号
        String updateId = inputStudentId(true);
        //3. 让用户录入要修改的学生对象信息
        //4. 根据新的学生信息封装新的学生对象
        Student newStu = inputStudentInfo(updateId);
        //5. 向服务端发送请求进行修改业务,将要修改的学生对象发送给服务端
        //service.updateStudentById(updateId, newStu);
        String receiveServer = sendDataToReceiveServer(Option.UPDATE_STUDENT+"&" + newStu.toString());
        //6. 给出修改结果的提示信息
        if ("true".equals(receiveServer)) {
            System.out.println("修改成功!");
        } else {
            System.out.println("修改失败!");
        }
    }

    //删除指定id的学生对象
    protected void deleteStudentById() {
        //1. 接收用户录入的要删除的学生学号
        String delId = inputStudentId(true);
        //3. 向服务端发送请求:进行删除业务,服务端返回信息
        String receiveServer = sendDataToReceiveServer(Option.DELETE_STUDNET+"&" + delId);
        //4. 给出用户: 删除结果的提示信息
        if ("true".equals(receiveServer)) {
            System.out.println("删除成功!");
        } else {
            System.out.println("删除失败!");
        }
    }


    //客户端中的查看学生方法
    public final void findAllStudents() {
        //向服务端发送信息表示客户端的操作是查找所有学生
        //返回学生信息的字符串表示形式
        String allStu = sendDataToReceiveServer(Option.FIND_STUDNET+"&void");
        //根据服务端返回的数据来组织对应的查看逻辑
        if (allStu == "") {
            System.out.println("没有找到你要的学生信息...请您尽快添加.");
        } else {
            //切割字符串获取学生对象字符串表现形式的数组
            String[] students = allStu.split("=");
            System.out.println("学号\t\t姓名\t年龄\t生日");
            for (String student : students) {
                //切割生成学生对象
                String[] stus = student.split(",");
                //根据切割内容创建对象
                Student stu = new Student(stus[0], stus[1], stus[2], stus[3]);
                //打印数据(学生对象)
                System.out.println(stu.getSid() + "\t" + stu.getName() + "\t" + stu.getAge() + "\t\t" + stu.getBirthday());
            }
        }
    }

    //客服中的添加学生功能
    public final void addStudent() {
        //1. 接收用户录入的学生学号
        String id = inputStudentId(false);

        //2. 将录入的数据封装为学生对象
        Student stu = inputStudentInfo(id);

        //发送指定格式的数据,receiveServer:并接收字符串形式的布尔值
        String receiveServer = sendDataToReceiveServer(Option.ADD_STUDNET+"&" + stu.toString());
        //4. 根据服务端返回的结果,组织对应的输出信息给用户: 添加成功/添加失败
        if ("true".equals(receiveServer)) {
            System.out.println("添加成功");
        } else {
            System.out.println("添加失败");
        }
    }

    // 键盘录入一个可用的学生id并返回
    public final String inputStudentId(boolean flag) {
        //1. 接收用户录入的要删除的学生学号
        System.out.println("请输入学生学号:");
        String id;
        while (true) {
            id = sc.next();
            String str = Option.ISEXISTS_STUDENT+"&" + id;
            //str是客户端发送给服务器的数据.data是服务器返回的布尔类型的数据(字符串形式)
            String data = sendDataToReceiveServer(str);
            //判断该id(地铁编号)是否满足需求,满足则跳出循环,否则继续录入地铁编号
            if ("true".equals(data) == flag) {
                break;
            } else {
                System.out.println("当前学号不可用,请重新录入:");
            }
        }
        return id;
    }

    //键盘录入学生信息,封装学生对象并返回
    public abstract Student inputStudentInfo(String id);

    //客户端登录功能的实现
    public void login() {
        //指定最多能登录几次
        for (int i = 1; i <= 3; i++) {
            //录入用户数据:姓名和密码
            System.out.println("请输入用户名: ");
            String name = sc.next();
            System.out.println("请输入密码:  ");
            String password = sc.next();
            //str是客户端发送给服务器的数据
            String str = Option.LOGIN_STUDENT+"&" + name + "," + password;
            //将用户登录相关的数据发送给服务端,并使用serverData接收服务端端发送来的数据
            String serverData = sendDataToReceiveServer(str);
            //判断服务端发送来的数据是否为true,是则登录成功,否则登录失败
            if ("true".equals(serverData)) {
                System.out.println("===================登录成功==================");
                break;
            } else {
                //登录失败:根据用户登录次数给出相应提示信息
                if (i == 3) {
                    System.out.println("您的机会已经用完了,请明天再来....");
                    System.exit(0);
                } else {
                    System.out.println("登录失败,您还有" + (3 - i) + "次机会");
                }
            }
        }
    }

    //该功能用来将str(数据)发送给服务端,并接收服务端返回的字符串信息
    public String sendDataToReceiveServer(String str) {
        //获得套接字,必须使用一个套接字,发送和接收数据,与服务端保持一致,否则出现异常,提示:套接字关闭
        Socket sk = getSocket();
        try {

            //创建一个字符缓冲输出流
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(sk.getOutputStream()));
            //将要发送的数据写入流中
            bw.write(str);
            //换行
            bw.newLine();
            //刷新流
            bw.flush();
            //中止字符缓冲输出流流
            sk.shutdownOutput();
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("异常.......");
        }
        String str1 = null;
        try {
            //创建一个字符缓冲输入流
            BufferedReader br = new BufferedReader(new InputStreamReader(sk.getInputStream()));
            //str1:读取服务端发送来的数据
            str1 = br.readLine();
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("getServerData方法异常...........");
        } finally {
            //返回服务端返回的信息
            return str1;
        }
    }

}
